package cn.tedu.charging.order.timer;

import cn.tedu.charging.common.pojo.po.ChargingBillExceptionPO;
import cn.tedu.charging.common.pojo.po.ChargingBillSuccessPO;
import cn.tedu.charging.common.protocol.WebSocketMessage;
import cn.tedu.charging.order.dao.mapper.ChargingBillExceptionMapper;
import cn.tedu.charging.order.dao.mapper.ChargingBillSuccessMapper;
import cn.tedu.charging.order.websocket.WebSocketServer;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 每个用户扫码下单之后 订单成功记录 success
 * 是否正常结束,不正常的订单满足
 * 1. 有success
 * 2. 定时方法一旦执行 时间绝对足够订单完成的 所以检查success订单的状态
 * 3. 如果订单结束 已支付 检查结束 但是如果订单依然正在充电 停止订单 记录excption 获取优惠券 通知用户充电异常
 */
@Component
@Slf4j
public class OrderExpCheckTimer {
    /**
     * 如果在消费者 和定时任务中直接调用 持久层 有点不符合分层的意义
     * 分层实际的目的 是为了解耦合,是为了保证业务稳定性.
     * 思考: 是否可以将http emqx rabbitmq timer-xxl-job 看成整个程序的入口层
     */
    @Autowired
    private ChargingBillSuccessMapper chargingBillSuccessMapper;
    //exceptionMapper
    @Autowired
    private ChargingBillExceptionMapper chargingBillExceptionMapper;
    //webSocket couponClient
    @Autowired
    private WebSocketServer webSocketServer;
    @XxlJob("checkSuccessStatus")
    public void checkSuccessStatus(String timerParam){
        log.debug("定时任务 执行订单异常检查");
        //补充xxl-job获取的参数
        timerParam=XxlJobContext.getXxlJobContext().getJobParam();
        //1.想办法解析这个json字符串 json的API方法支持我们单独解析其中的任意一个key-value键值对
        //{"orderNo":"123","userId":"24"} OrderTimerParam
        String orderNo=parseOrderNo(timerParam);
        Integer userId=parseUserId(timerParam);
        //2.获取successPO
        ChargingBillSuccessPO successPO=getSuccessByBillId(orderNo);
        if (successPO==null){
            //3.根本不存在 这个订单的成功信息,无法涉及到 异常单
            log.debug("订单异常检查,订单不存在");
            return;
        }else{
            //4.如果存在 判断订单状态 1充电中 2正常结束
            Integer billStatus = successPO.getBillStatus();
            log.debug("订单异常检查,订单状态为:{}",billStatus);
            if (billStatus!=null&&billStatus==1){
                //长时间 订单没有结束 还在充电中,修改订单状态为 异常结束,通知用户,记录异常单
                updateSuccessStatus(orderNo,3);
                //生成一个异常单
                saveSuccessException(orderNo);
                //给用户领取一个优惠券,通知用户 停止充电拔枪走人
                WebSocketMessage<String> webSocketMessage = new WebSocketMessage<>();
                webSocketMessage.setState(1);
                webSocketMessage.setMessage("exception");
                webSocketMessage.setData("A 您的订单存在异常,送您一张优惠券");
                webSocketServer.pushMessage(userId,JSON.toJSONString(webSocketMessage));

            }else{
                //说明succes不归当前定时任务管理
                return;
            }
        }
    }

    private void saveSuccessException(String orderNo) {
        ChargingBillExceptionPO exceptionPO=new ChargingBillExceptionPO();
        exceptionPO.setBillId(orderNo);
        //剩余的要从任务发起者 填补任务参数
        exceptionPO.setElectricity(new BigDecimal("1.09"));
        chargingBillExceptionMapper.insert(exceptionPO);
    }

    private void updateSuccessStatus(String orderNo, Integer status) {
        //update charging_bill_success set bill_status=3 where bill_id=#{orderNo}
        UpdateWrapper updateWrapper=new UpdateWrapper();
        //set 数据
        updateWrapper.setSql("bill_status="+status);
        //where 调教
        updateWrapper.eq("bill_id",orderNo);
        chargingBillSuccessMapper.update(null,updateWrapper);

    }

    private ChargingBillSuccessPO getSuccessByBillId(String orderNo) {
        //select * from charging_bill_success where bill_id=#{}
        QueryWrapper<ChargingBillSuccessPO> queryWrapper=new QueryWrapper();
        queryWrapper.eq("bill_id",orderNo);
        return chargingBillSuccessMapper.selectOne(queryWrapper);
    }

    private String parseOrderNo(String timerParam) {
        //如果入参参数 是json格式字符串 会创建一个JsonObject 不属于任何数据封装类
        //将key-value 解析成了一个map对象 orderNo=123 userId=24
        JSONObject jsonObject = JSON.parseObject(timerParam);
        return (String)jsonObject.get("orderNo");
    }
    private Integer parseUserId(String timerParam) {
        //如果入参参数 是json格式字符串 会创建一个JsonObject 不属于任何数据封装类
        //将key-value 解析成了一个map对象 orderNo=123 userId=24
        JSONObject jsonObject = JSON.parseObject(timerParam);
        return Integer.parseInt((String)jsonObject.get("userId"));
    }
}
